home *** CD-ROM | disk | FTP | other *** search
- {
- USING THE PROGRAM SEGMENT PREFIX (PSP) AS
- A TURBO PASCAL RECORD
-
- GARRY J. VASS [72307,3311]
-
- The program segement prefix is created by DOS
- whenever a program is initiated. It is 256 decimal
- bytes (100 hexidecimal bytes) long and contains a
- mixed-bag of information that can be used by a Turbo
- program. Some of the information in the PSP has
- been made obsolete by:
-
- 1. New releases of DOS; and
- 2. New releases of Turbo Pascal.
-
- For example, location 80 hex (128 decimal) contains
- the length of the command tail. Locations 81 hex
- and beyond contain the tail itself (the "command
- tail", by the way, are the parameters passed to
- a program. In the case of "format" the tail con-
- tains a drive specification, system option, and
- label option, such as, "a:/s/v".). The old days
- of de-coding the command tail are gone, however,
- replaced by Turbo's PARAMSTR(1), PARAMSTR(2), etc.
- functions.
-
- The File Control Blocks (FCB) went out with DOS 3,
- although it is still possible to use them.
-
- But several interesting items remain that can be
- found conveniently only in the PSP:
-
- 1. The address of the environment string; and
- 2. The amount of memory available.
-
- The segment address of the environment string is located
- at PSP address 2C hex (44 decimal). This is equivalent
- to absolute address CSEG:002C. (NOTE: If you are using
- debug, pepores, corelook, etc to check this out, remember
- that it will appear in low-byte-followed-by-high-byte
- format.)
-
- Decoding the environment string works as follows:
-
- 1. Set Eseg to MEM[Cseg:2C], or PSP.ENVIRONMENT_SEGMENT.
- Start with offset address zero;
- 2. Concatenate the character value of
- the byte at Eseg:offset to a character string;
- 3. Increment the offset address and
- repeat step 2.
- 4. If the byte at Eseg:offset is equal to zero,
- then one string has been found.
- 5. If two consequtive bytes are equal to zero,
- then you have reached the end of the environment
- area.
-
- Normally, the environment strings are 10 hex paragraphs long
- (or 160 decimal bytes). Some folks patch command.com and others
- use config.sys options to reset this value, and as Turbo programmers,
- we must accomodate them. (The easiest way to give yourself more
- environment space is to use the SHELL statement in your config.sys
- file. For example: SHELL=C:\COMMAND.COM /P /E:20, will give you
- 20 hex paragraphs.) This, combined with Turbo's limitation of
- 255 decimal bytes for a maximum string length, means that a REPEAT/
- UNTIL construct is necessary.
-
- Another item worth checking is the memory size DOS thinks it has.
- This is given in Cseg:0002, or PSP.MEMORY_SIZE_IN_PARAGRAPHS.
-
- The functions, ENVIRONMENT and MEMORY, provide at least one way
- of getting at these values.
-
- }
- PROGRAM PSP;
- TYPE
- ANYSTRING = STRING[255];
- PSPAREA = RECORD
- INT_20_INSTRUCTION :INTEGER;
- MEMORY_SIZE_IN_PARAGRAPHS :INTEGER;
- RESERVED_BYTE :BYTE;
- CALL_TO_DOS :ARRAY[1..05] OF BYTE;
- TERMINATE_VECTOR :ARRAY[1..02] OF INTEGER;
- BREAK_VECTOR :ARRAY[1..02] OF INTEGER;
- ERROR_VECTOR :ARRAY[1..02] OF INTEGER;
- USED_BY_DOS :ARRAY[1..22] OF BYTE;
- ENVIRONMENT_SEGMENT :INTEGER;
- DOS_WORK_AREA :ARRAY[1..34] OF BYTE;
- INT21_INSTRUCTIONS :ARRAY[1..03] OF BYTE;
- MORE_RESERVED :INTEGER;
- FCB_1_EXTENSION :ARRAY[1..07] OF BYTE;
- FCB_1 :ARRAY[1..09] OF BYTE;
- FCB_2_EXTENSION :ARRAY[1..07] OF BYTE;
- FCB_2 :ARRAY[1..20] OF BYTE;
- PARAMETER_LENGTH :BYTE;
- PARAMETERS :ARRAY[1..127] OF CHAR;
- END;
- VAR
- PSP :PSPAREA ABSOLUTE CSEG:$0000;
- I :INTEGER;
- OFFSET :INTEGER;
- MORE :BOOLEAN;
-
- FUNCTION REALNUMBER(R:INTEGER):REAL;
- BEGIN
- IF R < 0 THEN REALNUMBER := 65536.0 + R
- ELSE REALNUMBER := R;
- END;
-
- FUNCTION ENVIRONMENT(SEGMENT:INTEGER;VAR OFF:INTEGER; VAR MORE:BOOLEAN):ANYSTRING;
- {GET THE NEXT ASCIIZ STRING FROM THE ENVIRONMENT}
- VAR
- T : ANYSTRING;
- OFFSET : INTEGER;
- BEGIN
- T := '';
- OFFSET := OFF;
- REPEAT
- T := T + CHR(MEM[SEGMENT:OFFSET]);
- OFFSET := SUCC(OFFSET);
- UNTIL (MEM[SEGMENT:OFFSET] = 0);
- IF (MEM[SEGMENT:OFFSET + 0] = 0) AND
- (MEM[SEGMENT:OFFSET + 1] = 0) THEN MORE := FALSE
- ELSE MORE := TRUE;
- ENVIRONMENT := T;
- OFF := OFFSET;
- END;
-
- FUNCTION MEMORY(MEMORYSIZE:INTEGER):REAL;
- BEGIN
- MEMORY := REALNUMBER(MEMORYSIZE) * 16;
- END;
-
- BEGIN
- OFFSET := 0;
- REPEAT
- WRITELN('ENVIRONMENT STRING = ',ENVIRONMENT(PSP.ENVIRONMENT_SEGMENT,OFFSET,MORE));
- UNTIL NOT MORE;
- WRITELN('DOS THINKS IT HAS ',MEMORY(PSP.MEMORY_SIZE_IN_PARAGRAPHS):10:0,' BYTES AVAILABLE');
- END.
-
- y:
-
- 1. New releases of DOS; and
- 2. New releases of Turbo Pascal.
-
- For examp